<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台（PHP版）
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | gitee下载：https://gitee.com/likeshop_gitee/likeadmin
// | github下载：https://github.com/likeshop-github/likeadmin
// | 访问官网：https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\adminapi\logic;


use app\common\logic\BaseLogic;
use app\common\service\ConfigService;
use app\common\service\FileService;
use think\facade\Db;
use think\facade\Log;


/**
 * 工作台
 * Class WorkbenchLogic
 * @package app\adminapi\logic
 */
class WorkbenchLogic extends BaseLogic
{
    /**
     * @notes 工作套
     * @param $adminInfo
     * @return array
     * @author 段誉
     * @date 2021/12/29 15:58
     */
    public static function index($params)
    {

        return [

            //交易统计
            'transaction' => self::transaction($params),

            //卡位排名
            'card_used' => self::card_used(),

            //卡位状态
            'card_status' => self::card_status($params),

            //刷卡总额
            'summary' => self::summary(),

            //收款统计
            'payment' => self::payment($params),

            //供应商统计
            'card_bin_stat' => self::card_bin_stat($params),

        ];
    }


    /**
     * 5、总共的刷卡额，支付失败，退款；
     * 每个供应商的刷卡额、支付失败、退款；
     * @notes 刷卡总额
     * @return array
     */
    public static function summary()
    {
        $supplierStats =  Db::table('sr_system_summary_stats')
            ->field('card_bin,supplier_name,total_transaction_amount,success_transaction_amount,failure_transaction_amount,refund_transaction_amount')
//            ->where('stat_type', $params['stat_type'])
            ->order('id desc')
            ->select()
            ->toArray();
        // 获取全部供应商累计数据
        $totalStats = Db::table('sr_system_summary_stats')
            ->field([
                '0 as card_bin',
                '"全部" as supplier_name',
                'SUM(total_transaction_amount) as total_transaction_amount',
                'SUM(success_transaction_amount) as success_transaction_amount',
                'SUM(failure_transaction_amount) as failure_transaction_amount',
                'SUM(refund_transaction_amount) as refund_transaction_amount'
            ])
            ->select()
            ->toArray();
        // 将累计数据添加到结果数组开头
        array_unshift($supplierStats, $totalStats[0]);
        return $supplierStats;
    }



    /**
     * 商户交易增长率统计
     * @param array $params 查询参数
     * @return array
     */
    public static function transaction($params)
    {
        try {
            // 获取查询时间范围
            $statType = $params['stat_type'] ?? 'daily';
            $groupId = $params['group_id'] ?? 0;

            // 按统计类型过滤
            $query = Db::table('sr_growth_rate_stats')
                ->where('stat_type', $statType);


            // 按商户分组过滤
            if ($groupId) {
                $query->where('group_id', $groupId);
            }

            // 获取统计数据
            $stats = $query->order('stat_date', 'desc')
                ->select()
                ->toArray();

            // 处理数据
            $result = [];
            foreach ($stats as $stat) {
                $result[] = [
                    'stat_date' => $stat['stat_date'],
                    'stat_type' => $stat['stat_type'],
                    'group_id' => $stat['group_id'],
                    'group_name' => $stat['group_name'],
                    'total_amount' => round($stat['total_amount'], 2),
                    'total_amount_growth_rate' => round($stat['total_amount_growth_rate'], 2),
                    'failure_amount' => round($stat['failure_amount'], 2),
                    'failure_amount_growth_rate' => round($stat['failure_amount_growth_rate'], 2),
                    'failure_percentage' => $stat['total_amount'] > 0 ?
                        round(($stat['failure_amount'] / $stat['total_amount']) * 100, 2) : 0,
                    'refund_amount' => round($stat['refund_amount'], 2),
                    'refund_amount_growth_rate' => round($stat['refund_amount_growth_rate'], 2),
                    'refund_percentage' => $stat['total_amount'] > 0 ?
                        round(($stat['refund_amount'] / $stat['total_amount']) * 100, 2) : 0,
                ];
            }

            return $result;

        } catch (\Exception $e) {
            Log::error('商户交易增长率统计失败: ' . $e->getMessage());
            return [
                'code' => 500,
                'msg' => '统计失败：' . $e->getMessage(),
                'data' => []
            ];
        }
    }

    /**
     * 计算增长率
     * @param float $current 当前值
     * @param float $previous 上一个值
     * @return float
     */
    private static function calculateGrowthRate($current, $previous)
    {
        if ($previous == 0) {
            return $current > 0 ? 100 : 0;
        }
        return round((($current - $previous) / $previous) * 100, 2);
    }

    /**
     * 更新增长率统计数据
     * @param string $date 统计日期
     * @param string $type 统计类型
     * @return bool
     */
    public static function updateGrowthRateStats($date, $type = 'daily')
    {
        try {
            // 获取商户分组
            $groups = Db::name('group')->field('id, name')->select()->toArray();

            foreach ($groups as $group) {
                // 获取当前统计数据
                $currentStats = self::getGroupStats($date, $type, $group['id']);

                // 获取上一个周期的统计数据
                $previousDate = self::getPreviousDate($date, $type);
                $previousStats = self::getGroupStats($previousDate, $type, $group['id']);

                // 计算增长率
                $totalAmountGrowthRate = self::calculateGrowthRate(
                    $currentStats['total_amount'],
                    $previousStats['total_amount']
                );

                $failureAmountGrowthRate = self::calculateGrowthRate(
                    $currentStats['failure_amount'],
                    $previousStats['failure_amount']
                );

                $refundAmountGrowthRate = self::calculateGrowthRate(
                    $currentStats['refund_amount'],
                    $previousStats['refund_amount']
                );

                // 更新或插入数据
                $data = [
                    'stat_date' => $date,
                    'stat_type' => $type,
                    'group_id' => $group['id'],
                    'group_name' => $group['name'],
                    'total_amount' => $currentStats['total_amount'],
                    'total_amount_growth_rate' => $totalAmountGrowthRate,
                    'failure_amount' => $currentStats['failure_amount'],
                    'failure_amount_growth_rate' => $failureAmountGrowthRate,
                    'refund_amount' => $currentStats['refund_amount'],
                    'refund_amount_growth_rate' => $refundAmountGrowthRate,
                ];

                Db::name('growth_rate_stats')
                    ->where([
                        'stat_date' => $date,
                        'stat_type' => $type,
                        'group_id' => $group['id']
                    ])
                    ->insertOrUpdate($data);
            }

            return true;
        } catch (\Exception $e) {
            Log::error('更新增长率统计数据失败: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * 获取商户分组统计数据
     * @param string $date 统计日期
     * @param string $type 统计类型
     * @param int $groupId 商户分组ID
     * @return array
     */
    private static function getGroupStats($date, $type, $groupId)
    {
        $query = Db::name('transaction_record')
            ->where('group_id', $groupId);

        // 根据统计类型设置时间范围
        switch ($type) {
            case 'daily':
                $query->whereDay('transaction_date', $date);
                break;
            case 'weekly':
                $query->whereWeek('transaction_date', $date);
                break;
            case 'monthly':
                $query->whereMonth('transaction_date', $date);
                break;
        }

        $stats = $query->field([
            'SUM(transaction_amount) as total_amount',
            'SUM(CASE WHEN status = "failed" THEN transaction_amount ELSE 0 END) as failure_amount',
            'SUM(CASE WHEN status = "refunded" THEN transaction_amount ELSE 0 END) as refund_amount'
        ])->find();

        return [
            'total_amount' => $stats['total_amount'] ?? 0,
            'failure_amount' => $stats['failure_amount'] ?? 0,
            'refund_amount' => $stats['refund_amount'] ?? 0
        ];
    }

    /**
     * 获取上一个统计周期的日期
     * @param string $date 当前日期
     * @param string $type 统计类型
     * @return string
     */
    private static function getPreviousDate($date, $type)
    {
        switch ($type) {
            case 'daily':
                return date('Y-m-d', strtotime($date . ' -1 day'));
            case 'weekly':
                return date('Y-m-d', strtotime($date . ' -1 week'));
            case 'monthly':
                return date('Y-m-d', strtotime($date . ' -1 month'));
            default:
                return $date;
        }
    }

    private static function card_used(){
        return Db::table('sc_user_group')
            ->field('id,company_name,card_sum,card_used')
            ->order('card_sum desc')
            ->select()
            ->toArray();
    }

    private static function card_status($params){
        return Db::table('sr_card_status_detailed_stats')
            ->field([
                'stat_date',
                'stat_type',
                'active_cards',
                'active_rate',
                'cancelled_cards',
                'cancelled_rate',
                'frozen_cards',
                'frozen_rate',
                'available_slots',
                'total_cards',
                'ROUND(IF(total_cards > 0, (available_slots/total_cards) * 100, 0), 2) as available_rate'
            ])
            ->where($params)
            ->order('stat_date desc')
            ->limit(30)
            ->select()->toArray();
    }

    //每天、每周、每月，银行转账和二维码支付收款总额；
    private static function payment($params){
        return Db::table('sr_payment_method_stats')
            ->field([
                'stat_date',
                'stat_type',
                'payment_method',
                'total_amount',
            ])
            ->where(['stat_type' => $params['stat_type']])
            ->order('stat_date desc')
            ->limit(30)
            ->select()
            ->toArray();
    }

    /**
     * 供应商刷卡统计
     * @param array $params 查询参数
     * @return array
     */
    private static function card_bin_stat($params)
    {
        try {
            // 获取查询时间范围
            $startDate = $params['start_date'] ?? date('Y-m-d', strtotime('-30 days'));
            $endDate = $params['end_date'] ?? date('Y-m-d');
            $statType = $params['stat_type'] ?? 'daily';
            $supplierName = $params['supplier_name'] ?? '';

            // 构建基础查询
            $query = Db::table('sr_supplier_transaction_status_stats')
//                ->where('stat_date', 'between', [$startDate, $endDate])
                ->where('stat_type', $statType);
//                ->where('transaction_type', 'CARD_PAYMENT');

            if ($supplierName) {
                $query->where('supplier_name', $supplierName);
            }

            // 获取统计数据
            $stats = $query->field([
                'stat_date',
                'card_bin',
                'supplier_name',
                'SUM(CASE WHEN status_category = "成功类" THEN total_amount ELSE 0 END) as success_amount',
                'SUM(CASE WHEN status_category = "成功类" THEN total_count ELSE 0 END) as success_count',
                'SUM(CASE WHEN status_category = "失败类" THEN total_amount ELSE 0 END) as failure_amount',
                'SUM(CASE WHEN status_category = "失败类" THEN total_count ELSE 0 END) as failure_count',
                'SUM(CASE WHEN status_category = "退款类" THEN total_amount ELSE 0 END) as refund_amount',
                'SUM(CASE WHEN status_category = "退款类" THEN total_count ELSE 0 END) as refund_count',
                'SUM(total_count) as total_count'
            ])
            ->group('stat_date, card_bin, supplier_name')
            ->order('stat_date desc, success_amount desc')
            ->select()
            ->toArray();

            // 处理数据
            $result = [];
            foreach ($stats as $stat) {
                $totalCount = $stat['total_count'];
                $result[] = [
                    'stat_date' => $stat['stat_date'],
                    'card_bin' => $stat['card_bin'],
                    'supplier_name' => $stat['supplier_name'],
                    'success' => [
                        'amount' => round($stat['success_amount'], 2),
                        'count' => $stat['success_count'],
                        'rate' => $totalCount > 0 ? round(($stat['success_count'] / $totalCount) * 100, 2) : 0
                    ],
                    'failure' => [
                        'amount' => round($stat['failure_amount'], 2),
                        'count' => $stat['failure_count'],
                        'rate' => $totalCount > 0 ? round(($stat['failure_count'] / $totalCount) * 100, 2) : 0
                    ],
                    'refund' => [
                        'amount' => round($stat['refund_amount'], 2),
                        'count' => $stat['refund_count'],
                        'rate' => $totalCount > 0 ? round(($stat['refund_count'] / $totalCount) * 100, 2) : 0
                    ],
                    'total' => [
                        'amount' => round($stat['success_amount'] + $stat['failure_amount'] + $stat['refund_amount'], 2),
                        'count' => $totalCount
                    ]
                ];
            }

            // 计算总计数据
//            $totalStats = [
//                'success' => [
//                    'amount' => 0,
//                    'count' => 0
//                ],
//                'failure' => [
//                    'amount' => 0,
//                    'count' => 0
//                ],
//                'refund' => [
//                    'amount' => 0,
//                    'count' => 0
//                ],
//                'total' => [
//                    'amount' => 0,
//                    'count' => 0
//                ]
//            ];

//            foreach ($result as $stat) {
//                $totalStats['success']['amount'] += $stat['success']['amount'];
//                $totalStats['success']['count'] += $stat['success']['count'];
//                $totalStats['failure']['amount'] += $stat['failure']['amount'];
//                $totalStats['failure']['count'] += $stat['failure']['count'];
//                $totalStats['refund']['amount'] += $stat['refund']['amount'];
//                $totalStats['refund']['count'] += $stat['refund']['count'];
//                $totalStats['total']['amount'] += $stat['total']['amount'];
//                $totalStats['total']['count'] += $stat['total']['count'];
//            }
//
//            // 计算总计比率
//            if ($totalStats['total']['count'] > 0) {
//                $totalStats['success']['rate'] = round(($totalStats['success']['count'] / $totalStats['total']['count']) * 100, 2);
//                $totalStats['failure']['rate'] = round(($totalStats['failure']['count'] / $totalStats['total']['count']) * 100, 2);
//                $totalStats['refund']['rate'] = round(($totalStats['refund']['count'] / $totalStats['total']['count']) * 100, 2);
//            }

            return $result;
        } catch (\Exception $e) {
            Log::error('供应商刷卡统计失败: ' . $e->getMessage());
        }
    }
}